package clock.socoolby.com.clock;

import clock.socoolby.com.clock.utils.Constants;
import clock.socoolby.com.clock.utils.DateModel;
import clock.socoolby.com.clock.utils.PlayerManger;
import clock.socoolby.com.clock.utils.SharePerferenceModel;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Component;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.StackLayout;
import ohos.agp.components.Text;
import ohos.agp.text.Font;
import ohos.agp.window.service.WindowManager;
import ohos.app.Environment;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.Resource;
import ohos.global.resource.ResourceManager;
import ohos.miscservices.screenlock.ScreenLockController;
import ohos.miscservices.screenlock.interfaces.UnlockScreenCallback;
import ohos.powermanager.PowerManager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Timer;
import java.util.TimerTask;

public class MainAbility extends Ability implements Component.ClickedListener {
    private final static int SETTING_REQUEST_CODE = 100;

    private Text tvTime, tvDate, tvDay, tvDescript;
    private DependentLayout dlMain;
    private StackLayout slSetting;
    private Timer timer;
    private final static int UPDATE_TIME = 100;
    private SharePerferenceModel model;
    public final static int MODE_NORMAL = 200;
    public final static int MODE_SETTING_OTHER = 202;
    public int mMode = MODE_NORMAL;

    private boolean flag = false;
    private PowerManager.RunningLock runninglock;

    private EventHandler mHandler = new EventHandler(EventRunner.current()) {
        @Override
        protected void processEvent(InnerEvent event) {
            switch (event.eventId) {
                case UPDATE_TIME:
                    updateTime();
                    flag = !flag;
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        getWindow().addFlags(WindowManager.LayoutConfig.MARK_FULL_SCREEN);
        getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_NAVIGATION);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initView();
        initData();
        timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                mHandler.sendEvent(UPDATE_TIME);
            }
        };
        timer.schedule(timerTask, 1000, 1000);
        PowerManager powerManager = new PowerManager();
        runninglock = powerManager.createRunningLock("Lock", PowerManager.RunningLockType.BACKGROUND);
    }

    @Override
    protected void onActive() {
        super.onActive();
        if (runninglock != null) {
            runninglock.lock(Integer.MAX_VALUE);
        }
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        if (runninglock != null) {
            runninglock.unLock();
        }
    }

    private void initData() {
        model = new SharePerferenceModel();
        model.read();
        LogUtil.loge("========>model:" + model.toString());
        if (model.getDescription() != null) {
            tvDescript.setText(model.getDescription());
        }

        // TODO 启动服务
    }


    private void initView() {
        tvTime = (Text) findComponentById(ResourceTable.Id_tv_time);
        tvDate = (Text) findComponentById(ResourceTable.Id_tv_date);
        tvDay = (Text) findComponentById(ResourceTable.Id_tv_day);
        tvDescript = (Text) findComponentById(ResourceTable.Id_tv_descript);
        dlMain = (DependentLayout) findComponentById(ResourceTable.Id_dl_main);
        slSetting = (StackLayout) findComponentById(ResourceTable.Id_sl_setting);
        Font font = parseAttributes();
        tvTime.setFont(font);
        tvDate.setFont(font);
        tvTime.setClickedListener(this);
        dlMain.setClickedListener(this);
        slSetting.setClickedListener(this);
    }


    private void updateTime() {
        DateModel date = new DateModel();
        String dateString = date.getDateString();
        String dayString = date.getToday();
        String timeString = model.isDisplaySecond() ? date.getTimeString() : date.getShortTimeString();
        timeString = timeString.replace("1", " 1");
        if (timeString.startsWith(" ")) {
            timeString = timeString.substring(1);
        }
        tvTime.setText(timeString);
        tvDate.setText(dateString.replace("1", " 1"));
        tvDay.setText(dayString);
        reportTime(date);
    }

    private void reportTime(DateModel date) {
        if (model.isTickSound()) {
            PlayerManger.getInstance().playTick(this);
        }
        int year = date.getYear();
        int month = date.getMonth();
        int day = date.getDay();
        int hour = date.getHour();
        int minute = date.getMinute();
        int second = date.getSecond();
        int today = date.getWeek();
        if (model.getTypeHourPower() != Constants.TALKING_NO_REPORT) {
            if ((minute == 30 || minute == 0) && model.getTypeHourPower() == Constants.TALKING_HALF_AN_HOUR && second == 0) {
                LogUtil.loge(String.format("======>reportTime Year:%d Month:%d Day:%d Hour:%d Minute:%d Today:%d", year, month, day, hour, minute, today));
                if (isReport(hour, minute)) {
                    PlayerManger.getInstance().reportTime(this, year, month, day, hour, minute, today);
                }
            } else if (model.getTypeHourPower() == Constants.TALKING_HOURS && minute == 0 && second == 0) {
                if (isReport(hour, minute)) {
                    PlayerManger.getInstance().reportTime(this, year, month, day, hour, minute, today);
                }
            }
        }
    }

    private boolean isReport(int hour, int minute) {
        DateModel startTime = model.getStartHourPowerTime();
        DateModel stopTime = model.getStopHourPowerTime();
        DateModel nowTime = new DateModel();
        nowTime.setTime(hour, minute);

        if (startTime.getShortTimeString().equals(stopTime.getShortTimeString()))
            return true;
        long minutes = startTime.minusTime(stopTime);
        if (minutes < 0) {//stop>start
            return nowTime.minusTime(startTime) < 0 || nowTime.minusTime(stopTime) > 0;
        }
        return true;
    }


    /**
     * Custom font
     *
     * @return font
     */
    private Font parseAttributes() {
        ResourceManager resManager = getContext().getResourceManager();
        RawFileEntry rawFileEntry = resManager.getRawFileEntry("resources/rawfile/fonts/ds_digi.ttf");
        Resource resource = null;

        File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "ds_digi.ttf");
        OutputStream outputStream = null;
        try {
            resource = rawFileEntry.openRawFile();
            outputStream = new FileOutputStream(file);
            int index;
            byte[] bytes = new byte[1024];
            while ((index = resource.read(bytes)) != -1) {
                outputStream.write(bytes, 0, index);
                outputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (resource != null) {
                    resource.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Font.Builder builder = new Font.Builder(file);
        return builder.build();

    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_dl_main:
                switchMode(MODE_SETTING_OTHER);
                break;
            case ResourceTable.Id_tv_time:
                switchMode(MODE_SETTING_OTHER);
                break;
            case ResourceTable.Id_sl_setting:
                openSettingAbility();
                break;
        }
    }

    private void openSettingAbility() {
        Intent intent = new Intent();
        Operation opt = new Intent
                .OperationBuilder()
                .withBundleName(getBundleName())
                .withAbilityName(SettingAbility.class.getCanonicalName())
                .build();
        intent.setOperation(opt);
        startAbilityForResult(intent, SETTING_REQUEST_CODE);
        switchMode(MODE_NORMAL);
    }


    private void switchMode(int mode) {
        switch (mode) {
            case MODE_NORMAL:
                slSetting.setVisibility(Component.HIDE);
                break;
            case MODE_SETTING_OTHER:
                slSetting.setVisibility(Component.VISIBLE);
                break;
        }
        mMode = mode;
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        super.onAbilityResult(requestCode, resultCode, resultData);
        if (requestCode == SETTING_REQUEST_CODE) {
            initData();
        }
    }

    @Override
    protected void onBackPressed() {
        switchMode(MODE_NORMAL);
    }
}
